from app.forms.token import TokenForm
from app.libs.error_code import AuthFailed
from app.libs.redprint import Redprint
from app.forms.user import ClientForm
from flask import request, current_app, jsonify
from app.libs.enums import ClientTypeEnum
from app.models.user import User
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer, SignatureExpired, BadSignature
from datetime import datetime


red_token = Redprint('token')


@red_token.route('/token', methods=['POST'])
def get_token():
    ''' 登陆 '''
    form = ClientForm(request.json)
    form.validate_for_api()
    can_login = {
        ClientTypeEnum.USER_EMAIL: User.verify
    }
    user_info = can_login[form.type.data](form.account.data, form.secret.data)

    token = generate_auth_token(user_info['uid'], form.type.data, user_info['scope'])
    t = {'token': token.decode('ascii')}
    return jsonify(t), 201


@red_token.route('/tokne/info', methods=['POST'])
def get_token_info():
    form = TokenForm(request.json)
    form.validate_for_api()
    s = Serializer(current_app.config['SECRET_KEY'])
    try:
        token_dict = s.loads(form.token.data, return_header=True)
    except BadSignature:
        raise AuthFailed(msg='token error')
    except SignatureExpired:
        raise AuthFailed(msg='token expired')

    r = {
        'create_time': datetime.fromtimestamp(token_dict[1]['iat']),
        'expire_time': datetime.fromtimestamp(token_dict[1]['exp']),
    }

    return jsonify(r)


def generate_auth_token(uid, ac_type, scope):
    # 构建token
    s = Serializer(current_app.config['SECRET_KEY'],
                   current_app.config['TOKEN_EXPIRATION'])
    return s.dumps({
        'uid': uid,
        'ac_type': ac_type.value,
        'scope': scope
    })
